package com.uama.audio.util;

import android.content.Context;
import android.os.Bundle;
import android.os.Environment;
import android.text.TextUtils;
import android.util.Log;

import com.iflytek.cloud.RecognizerListener;
import com.iflytek.cloud.RecognizerResult;
import com.iflytek.cloud.SpeechConstant;
import com.iflytek.cloud.SpeechError;
import com.iflytek.cloud.SpeechRecognizer;
import com.iflytek.cloud.SpeechUtility;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import cafe.adriel.androidaudioconverter.AndroidAudioConverter;
import cafe.adriel.androidaudioconverter.callback.IConvertCallback;
import cafe.adriel.androidaudioconverter.callback.ILoadCallback;
import cafe.adriel.androidaudioconverter.model.AudioFormat;

/**
 * @author wenhu Tong
 * @email wenhu.tong@uama.com.cn
 * @date 2017/11/9 14:03
 * @desc
 */
public class SpeechManager {
    private static final String TAG = "SpeechManager";
    private static volatile SpeechManager mInstance = new SpeechManager();
    private Context mContext;
    private String mAudioDir;
    private String mSourcePath;
    private String mTargetPath;
    private String mMp3Path;


    private SpeechManager() {
    }

    public interface ConvertListener {
        void onSuccess(File file);

        void onFailed(Exception e);
    }

    public interface SpeechListener {
        void onVolumeChanged(int i, byte[] bytes);

        void onResult(String result);

        void onError(int code, String error);
    }

    public void init(Context context) {
        mContext = context.getApplicationContext();
        mAudioDir = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "uama";
        initPath(mAudioDir);

        SpeechUtility.createUtility(context, SpeechConstant.APPID + "=5a004126");
        initConvert(context);
    }


    public static SpeechManager getInstance() {
        return mInstance;
    }

    public SpeechRecognizer getRecognizer() {
        SpeechRecognizer recognizer;
        recognizer = SpeechRecognizer.createRecognizer(mContext, null);
        // 清空参数
        recognizer.setParameter(SpeechConstant.PARAMS, null);
        // 设置听写引擎
        recognizer.setParameter(SpeechConstant.ENGINE_TYPE, SpeechConstant.TYPE_CLOUD);
        recognizer.setParameter(SpeechConstant.DOMAIN, "iat");
        recognizer.setParameter(SpeechConstant.LANGUAGE, "zh_cn");
        recognizer.setParameter(SpeechConstant.ACCENT, "mandarin ");
        recognizer.setParameter(SpeechConstant.AUDIO_FORMAT, "wav");
        recognizer.setParameter(SpeechConstant.ASR_AUDIO_PATH, mSourcePath);
//        mIat.setParameter(SpeechConstant.KEY_SPEECH_TIMEOUT,"5000");
        recognizer.setParameter(SpeechConstant.VAD_EOS, "8000");
        return recognizer;
    }

    public void startSpeech(SpeechRecognizer recognizer, final SpeechListener listener) {
        recognizer.startListening(new RecognizerListener() {
            private String descContent= "";
            private List<String> mResults = new ArrayList();

            @Override
            public void onVolumeChanged(int i, byte[] bytes) {
                if(listener != null){
                    listener.onVolumeChanged(i, bytes);
                }
            }

            @Override
            public void onBeginOfSpeech() {

            }

            @Override
            public void onEndOfSpeech() {

            }

            @Override
            public void onResult(RecognizerResult results, boolean isLast) {
                connectResults(results);
                if (isLast) {
                    setData();
                }
            }

            @Override
            public void onError(SpeechError error) {
                if(listener != null){
                    listener.onError(error.getErrorCode(), error.getErrorDescription());
                }
            }

            @Override
            public void onEvent(int i, int i1, int i2, Bundle bundle) {

            }

            private void setData() {
                StringBuffer resultBuffer = new StringBuffer();

                for (int i = 0; i < mResults.size(); ++i) {
                    resultBuffer.append(mResults.get(i));
                }
                descContent += resultBuffer.toString();
                if(listener != null && !TextUtils.isEmpty(descContent)){
                    listener.onResult(descContent);
                }
                SpeechManager.getInstance().mergeAudio();

            }

            private void connectResults(RecognizerResult results) {
                String text = JsonParser.parseIatResult(results.getResultString());

                String sn = null;
                // 读取json结果中的sn字段
                try {
                    JSONObject resultJson = new JSONObject(results.getResultString());
                    sn = resultJson.optString("sn");
                } catch (JSONException e) {
                    e.printStackTrace();
                }

                mResults.add(text);
            }
        });
    }

    public void stopSpeech(SpeechRecognizer recognizer) {
        recognizer.stopListening();
    }

    public void mergeAudio() {
        try {
            if (FileUtil.isFileExist(mTargetPath)) {
                WavUtil.mergeWav(new File(mSourcePath), new File(mTargetPath));
                Log.d(TAG, "merge audio");
            } else {
                FileUtil.reNameFile(mSourcePath, mTargetPath);
                Log.d(TAG, "rename File: " + mTargetPath);
            }
        } catch (IOException e) {
            e.printStackTrace();
            Log.e(TAG, "merge error");
        }
    }


    public void convertToMp3(final ConvertListener listener) {
        if (!FileUtil.isFileExist(mTargetPath)) {
            return;
        }
        AndroidAudioConverter.with(mContext)
                .setFile(new File(mTargetPath))
                .setFormat(AudioFormat.MP3)
                .setCallback(new IConvertCallback() {
                    @Override
                    public void onSuccess(File file) {
                        if (listener != null) {
                            listener.onSuccess(file);
                        }
                    }

                    @Override
                    public void onFailure(Exception e) {
                        if (listener != null) {
                            listener.onFailed(e);
                        }
                    }
                })
                .convert();
    }

    public void clearAudio() {
        FileUtil.deleteFile(mSourcePath);
        FileUtil.deleteFile(mTargetPath);
        FileUtil.deleteFile(mMp3Path);
    }

    public void setAudioDir(String mAudioDir) {
        this.mAudioDir = mAudioDir;
        initPath(mAudioDir);
    }

    public String getMp3Path() {
        return mMp3Path;
    }

    private void initListener() {

    }

    private void initConvert(Context context) {
        AndroidAudioConverter.load(context, new ILoadCallback() {
            @Override
            public void onSuccess() {
                // Great!
            }

            @Override
            public void onFailure(Exception error) {
                error.printStackTrace();
                // FFmpeg is not supported by device
            }
        });
    }

    private void initPath(String audioDir) {
        FileUtil.mkDir(audioDir);
        mSourcePath = audioDir + File.separator + "source.wav";
        mTargetPath = audioDir + File.separator + "target.wav";
        mMp3Path = audioDir + File.separator + "target.mp3";
    }


}
